package store

import (
	"fmt"
	baseConfig "gitee.com/zaiqiang231/go-base-app/base_app/config"
	baseDatabase "gitee.com/zaiqiang231/go-base-app/base_app/database"
	baseLog "gitee.com/zaiqiang231/go-base-app/base_app/log"
	"gitee.com/zaiqiang231/lovesport-authz-service/app/constant"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"log"
	"os"
	"sync"
	"time"
)

type Datastore struct {
	db *gorm.DB
}

var (
	datastore          *Datastore
	onceStore          sync.Once
	defaultLogPath     = "./log_record"
	defaultLogFileName = "mysql.log"
)

func InitDataStore(opts *baseConfig.MysqlConfig) (*Datastore, error) {
	if opts == nil && datastore == nil {
		return nil, fmt.Errorf("failed to get mysql store fatory, opts:%v datastore: %v", opts, datastore)
	}
	var err error
	var dbIns *gorm.DB
	onceStore.Do(func() {
		baseLog.Infof("InitDataStore %v-%v", opts.Host, opts.Database)
		os.MkdirAll(defaultLogPath, os.ModePerm)
		logFile, _ := os.OpenFile(defaultLogPath+"/"+defaultLogFileName, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0777)
		options := &baseDatabase.Options{
			Host:                  opts.Host,
			Username:              opts.Username,
			Password:              opts.Password,
			Database:              opts.Database,
			MaxIdleConnections:    opts.MaxIdleConnections,
			MaxOpenConnections:    opts.MaxOpenConnections,
			MaxConnectionLifeTime: time.Duration(opts.MaxConnectionLifeTime) * time.Second,
			Logger: logger.New(log.New(logFile, "\r\n", log.LstdFlags), logger.Config{
				SlowThreshold:             200 * time.Millisecond,
				LogLevel:                  logger.Info,
				IgnoreRecordNotFoundError: false,
				Colorful:                  true,
			}),
		}
		dbIns, err = baseDatabase.NewMysqlDb(options)
		if err != nil {
			baseLog.Errorf("failed to open mysql")
			return
		}
		datastore = &Datastore{dbIns}
	})

	if datastore == nil {
		return nil, constant.ErrFailedGetStore
	}
	return datastore, nil
}

func GetDataStore() *Datastore {
	if datastore == nil {
		baseLog.Errorf("datastore instance is %v", datastore)
	}
	return datastore
}
